library(png)
format(Sys.time(), format="%d_%b_%Y")
[1] "27_Feb_2017"
## First consolidate the available files into a single table
path <- "~/Box Sync/Four model compare/Module 2 extinct"
setwd(path)
Error in setwd(path) : cannot change working directory
load('~/Box Sync/colliding ranges/Simulations_humans/Results/available daily summaries/Four_model_compare_results_02_Mar_2017_crop_to_3481.Rdata')
extant <- Concatenated_data
extant
setwd("~/Box Sync/colliding ranges/Simulations_humans/Results/available daily summaries")
The working directory was changed to /Users/Ty/Box Sync/colliding ranges/Simulations_humans/Results/available daily summaries inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
details <- file.info(list.files())
trimmed_details <- details[which(list.files() == list.files(pattern = "Four_model_compare_results_extinct*")),]
ord <- order(trimmed_details$mtime, decreasing = TRUE)
rownames(trimmed_details[ord,])[1]
[1] "Four_model_compare_results_extinct_10_Mar_2017.Rdata"
load(rownames(trimmed_details[ord,])[1])
extinct <- Concatenated_data
trimmed_details <- details[which(list.files() != list.files(pattern = "Four_model_compare_results_extinct*")),]
ord <- order(trimmed_details$mtime, decreasing = TRUE)
rownames(trimmed_details[ord,])[1]
[1] "Four_model_compare_results_10_Mar_2017_crop_to_4897.Rdata"
load(rownames(trimmed_details[ord,])[1])
extant <- Concatenated_data
dim(extinct)
[1] 25492 62
dim(extant)
[1] 14660 62
for(i in c(9,10,11,12,14,15,16,17,19,20,21,22,24,25,26,27,29,30,31,32)){
extinct[which(is.nan(as.numeric(as.character(extinct[, i]))) == TRUE), i] <- NA
}
for(i in c(9,10,11,12,14,15,16,17,19,20,21,22,24,25,26,27,29,30,31,32)){
extant[which(is.nan(as.numeric(as.character(extant[, i]))) == TRUE), i] <- NA
}
i <- 19
for(i in c(20,21,24,25,26,27)){
extinct[which(as.numeric(as.character(extinct[, i])) == 0), i] <- NA
}
for(i in c(20,21,24,25,26,27)){
extant[which(as.numeric(as.character(extant[, i])) == 0), i] <- NA
}
xlimit <- c(0,1)
ylimit <- c(0,600)
maincex <- 0.9
png(file="Global_success_rate_per_parameter.png", width=8.5, height=11, units="in", res=300)
par(mfrow=c(5,4), mar=c(3,3,3,0))
hist(as.numeric(as.character(extinct[,9])), main="speciation of F in F env", col=adjustcolor("firebrick", alpha=0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[,9])), main="speciation of F in F env", col=adjustcolor("cornflowerblue", alpha=0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[,10])), main="speciation of D in F env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[,10])), main="speciation of D in F env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[,11])), main="speciation of F in D env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[,11])), main="speciation of F in D env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[,12])), main="speciation of D in D env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[,12])), main="speciation of D in D env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
#######
hist(as.numeric(as.character(extinct[, 14])), main="extinction of F in F env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 14])), main="extinction of F in F env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 15])), main="extinction of D in F env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 15])), main="extinction of D in F env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 16])), main="extinction of F in D env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 16])), main="extinction of F in D env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 17])), main="extinction of D in D env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 17])), main="extinction of D in D env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
######
hist(as.numeric(as.character(extinct[, 29])), main="arisal of F in F env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 29])), main="arisal of F in F env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 30])), main="arisal of D in F env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 30])), main="arisal of D in F env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 31])), main="arisal of F in D env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 31])), main="arisal of F in D env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 32])), main="arisal of D in D env", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 32])), main="arisal of D in D env", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
######
hist(as.numeric(as.character(extinct[, 19])), main="NOPE -- Diffusion: source F, target F", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= c(0,18000), cex.main= maincex)
hist(as.numeric(as.character(extant[, 19])), main="NOPE -- Diffusion: source F, target F", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= c(0,18000), cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 20])), main="Diffusion: source D, target F", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 20])), main="Diffusion: source D, target F", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 21])), main="Diffusion: source F, target D", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 21])), main="Diffusion: source F, target D", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 22])), main="NOPE -- Diffusion: source D, target D", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= c(0,18000), cex.main= maincex)
hist(as.numeric(as.character(extant[, 22])), main="NOPE -- Diffusion: source D, target D", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= c(0,18000), cex.main= maincex, add=TRUE)
####
hist(as.numeric(as.character(extinct[, 24])), main="Takeover: source F, target F", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 24])), main="Takeover: source F, target F", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 25])), main="Takeover: source D, target F", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 25])), main="Takeover: source D, target F", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 26])), main="Takeover: source F, target D", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 26])), main="Takeover: source F, target D", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
hist(as.numeric(as.character(extinct[, 27])), main="Takeover: source D, target D", col=adjustcolor("firebrick", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex)
hist(as.numeric(as.character(extant[, 27])), main="Takeover: source D, target D", col=adjustcolor("cornflowerblue", alpha= 0.7), breaks=100, border=NA, xlim= xlimit, ylim= ylimit, cex.main= maincex, add=TRUE)
dev.off()
null device
1
png(file="extiction minus extant per outcome.png", width=8.5, height=11, units="in", res=300)
par(mfrow=c(3,1))
plot(as.numeric(as.character(extinct[,9])), as.numeric(as.character(extinct[,14])), xlab="speciation", ylab="extinction", col= adjustcolor("firebrick", alpha=0.2), pch=19, cex=0.6, ylim=c(0,1))
plot(as.numeric(as.character(extant[,9])), as.numeric(as.character(extant[,14])), xlab="speciation", ylab="extinction", col= adjustcolor("cornflowerblue", alpha=0.2), pch=19, cex=0.6, ylim=c(0,1))
plot(as.numeric(as.character(extinct[,9])), as.numeric(as.character(extinct[,14])), xlab="speciation", ylab="extinction", col= adjustcolor("firebrick", alpha=0.2), pch=19, cex=0.6, ylim=c(0,1))
points(as.numeric(as.character(extant[,9])), as.numeric(as.character(extant[,14])), xlab="speciation", ylab="extinction", col= adjustcolor("cornflowerblue", alpha=0.2), pch=19, cex=0.6)
dev.off()
null device
1
xfit1 <- seq(xmin, xmax, length= 100)
Error in is.finite(from) :
default method not implemented for type 'closure'
load('~/Box Sync/colliding ranges/Simulations_humans/Available trees/real.analysis.RData')
Concatenated_data <- extant
#Concatenated_data <- Concatenated_data[Concatenated_data[, 2] == "stats.no.bTO", ]
#Concatenated_data <- Concatenated_data[Concatenated_data[, 6] != "05", ]
# Concatenated_data[, 6] <- as.numeric(Concatenated_data[, 6])
# # Concatenated_data[original[, 2] == "background_takeover", 6] <- Concatenated_data[original[, 2] == "background_takeover", 6] + 4
Concatenated_data[, 6] <- factor(Concatenated_data[, 6])
#head(Concatenated_data)
#names(Concatenated_data)
PCAdata <- Concatenated_data[, -(1:35)]
PCAdata <- PCAdata[, -12]
PCAdata <- apply(PCAdata, 2, as.numeric)
remove <- apply(is.na(PCAdata), 1, any)
PCAdata <- PCAdata[!remove, ]
# Predictions
library(randomForest)
randomForest 4.6-12
Type rfNews() to see new features/changes/bug fixes.
data.analysis.comp2 <- data.frame("Model" = as.factor(Concatenated_data[!remove, 6]),
PCAdata)
data.analysis.comp2$sprate <- data.analysis.comp2$trait_1_speciation/data.analysis.comp2$trait_2_speciation
data.analysis.comp2$extrate <- data.analysis.comp2$trait_1_extinction/data.analysis.comp2$trait_2_extinction
#load("Real_phy/real.analysis.RData")
a <- as.data.frame(real.analysis$results_summary_of_single_value_outputs)
a$sprate <- a$trait_1_speciation / a$trait_2_speciation
a$extrate <- a$trait_1_extinction / a$trait_2_extinction
data.analysis.comp3 <- data.analysis.comp2[, -c(2, 13:14, 16:20)]
#data.analysis.comp3 <- data.analysis.comp3[data.analysis.comp3$Model %in% 1:4, ]
#data.analysis.comp3$Model <- factor(data.analysis.comp3$Model)
#sub <- unlist(lapply(as.list(c(1:4)), function(x, y) {
# sample(which(y$Model == x), min(table(data.analysis.comp3$Model)))},
# y = data.analysis.comp3))
# data.analysis.comp3 <- data.analysis.comp3[sub, ]
fun <- function(x, y, per = .33) {sample(which(y$Model == x), round(table(y$Model)[1]*per))}
sub.test <- unlist(lapply(as.list(paste0(0, c(1:4))), fun,
y = data.analysis.comp3))
test2 <- data.analysis.comp3[sub.test, 2:ncol(data.analysis.comp3)]
test1 <- data.analysis.comp3[sub.test, 1]
train <- data.analysis.comp3[-sub.test, ]
for(i in 1:100){
(fit <- randomForest(Model ~ ., data=train, xtest = test2, ytest = test1,
importance=TRUE, ntree=1000, keep.forest = TRUE, replace=FALSE))
predictions <- predict(fit,
a,
type="prob")
predictions
save(fit, file=paste0("~/Box Sync/colliding ranges/Simulations_humans/Results/RF_daily_output/RF_daily_output_", format(Sys.time(), format="%d_%b_%Y"), "_",i, "_NoREPLACEMENT_.Rdata"))
}
save(fit, file=paste0("~/Box Sync/colliding ranges/Simulations_humans/Results/RF_daily_output/RF_daily_output_", format(Sys.time(), format="%d_%b_%Y"),".Rdata"))
plot(fit, ylim=c(0,1))

labs <- c("Basic", "+Diffusion", "+Takeover", "+Diffusion +Takeover")
# bar plot
png("Prob_aus.png", width = 25, height = 25, res = 300, units = "in")
par(mar = c(8, 8, 1, 1))
pred <- setNames(as.numeric(predictions), labs)
cols <- rev(c("darkgreen", "red", "blue", "darkorange1"))
barplot(pred, col = cols, ylab = "Proability", cex.lab = 3, cex.names = 2)
dev.off()
null device
1
# Plot confusion matrix
png("Conffusion_matrix_all.png", width = 25, height = 25, res=300, units="in")
par(mar = c(10, 11, 1, 1))
colors1 <- colorRampPalette(colors = c("#f0f0f0", "#bdbdbd","#636363"))
prop <- apply(fit$confusion[, -5], 2, function(x){x / sum(x)}) * 100
image(prop, col = colors1(20), axes=FALSE)
axis(1, at=c(0, .33, .66, 1), labels=labs, tick = FALSE, line = FALSE, cex.axis = 3.5, pos = -.19)
axis(2, at=c(0, .33, .66, 1), labels=labs, tick = FALSE, line = FALSE, cex.axis = 3.5)
mtext("ACTUAL", side = 1, padj = 3, cex = 4)
mtext("PREDICTED", side = 2, padj = -3, cex = 4)
for(i in 1:4) {
for(j in 1:4) {
text(x = c(0, .33, .66, 1)[i], y = c(0, .33, .66, 1)[j], paste0(round(prop[i, j], 2), "%"),
cex = 5)
}
}
dev.off()
null device
1
importance(fit)
01 02 03
Pylo_diversity_is_sum_of_BL 36.68603 25.692246 44.88765
average_phylogenetic_diversity_is_mean_of_BL 43.12789 34.908001 47.98480
variance_Pylo_diversity_is_variance_of_BL 38.00313 20.262707 19.18043
F_quadratic_entropy_is_sum_of_PD 28.49584 23.877597 40.27946
Mean_pairwise_distance 35.73981 27.249223 32.09020
variance_pairwise_distance 39.27909 38.069218 40.92584
Evolutionary_distinctiveness_sum 37.35990 28.081845 45.31515
mean_Phylogenetic_isolation 41.20750 35.209163 48.94046
variance_Phylogenetic_isolation 35.88075 6.978819 28.67514
gamma 27.59011 28.762859 76.57843
extinction_per_speciation 11.04195 51.084694 65.78277
transition_from_trait_1_to_2 28.53323 27.846818 47.04102
transition_from_trait_2_to_1 36.78696 30.942883 50.69606
transition_rate_ratio_1to2_over_2to1 54.87487 38.192677 38.58033
Phylogenetic_signal 66.29483 45.359260 70.57335
spatial.tests.fora 53.03264 95.790134 98.20864
spatial.tests.dom 86.83866 40.905940 53.51233
prevalence 55.09973 15.677005 39.96226
sprate 57.87711 32.873304 105.88921
extrate 29.72153 29.191046 40.11454
04 MeanDecreaseAccuracy
Pylo_diversity_is_sum_of_BL 45.89839 67.10212
average_phylogenetic_diversity_is_mean_of_BL 35.72290 71.53199
variance_Pylo_diversity_is_variance_of_BL 31.31532 59.79845
F_quadratic_entropy_is_sum_of_PD 42.73530 76.03108
Mean_pairwise_distance 42.95949 69.53536
variance_pairwise_distance 37.44388 76.20714
Evolutionary_distinctiveness_sum 46.70827 67.45126
mean_Phylogenetic_isolation 36.35073 72.84609
variance_Phylogenetic_isolation 23.59933 50.96412
gamma 51.86023 104.53469
extinction_per_speciation 53.99058 87.53765
transition_from_trait_1_to_2 36.98221 64.93037
transition_from_trait_2_to_1 42.85645 68.22442
transition_rate_ratio_1to2_over_2to1 51.09836 93.31104
Phylogenetic_signal 46.37239 91.08957
spatial.tests.fora 76.18005 138.82996
spatial.tests.dom 64.49868 119.35092
prevalence 64.89918 86.99762
sprate 41.98590 109.24396
extrate 37.94293 69.14048
MeanDecreaseGini
Pylo_diversity_is_sum_of_BL 271.5521
average_phylogenetic_diversity_is_mean_of_BL 241.4081
variance_Pylo_diversity_is_variance_of_BL 222.2757
F_quadratic_entropy_is_sum_of_PD 247.9364
Mean_pairwise_distance 272.9117
variance_pairwise_distance 259.1696
Evolutionary_distinctiveness_sum 277.8165
mean_Phylogenetic_isolation 241.4813
variance_Phylogenetic_isolation 220.4116
gamma 283.5771
extinction_per_speciation 340.7512
transition_from_trait_1_to_2 335.8418
transition_from_trait_2_to_1 356.5606
transition_rate_ratio_1to2_over_2to1 288.0278
Phylogenetic_signal 418.6853
spatial.tests.fora 536.9193
spatial.tests.dom 344.7908
prevalence 303.3840
sprate 342.5898
extrate 260.9412
# Variables importance
imp <- importance(fit)
imp <- apply(imp, 2, function(x) (x - min(x))/(max(x) - min(x)))
imp <- imp[sort(imp[, 5], index.return = TRUE, decreasing = TRUE)$ix, ]
names <- rownames(imp)
names[names == "spatial.tests.fora"] <- "Space F"
names[names == "spatial.tests.dom"] <- "Space D"
names[names == "sprate"] <- "Sp(ratio)"
names[names == "transition_from_trait_1_to_2"] <- "TR(1-2)"
names[names == "transition_from_trait_2_to_1"] <- "TR(2-1)"
names[names == "Phylogenetic_signal"] <- "PhySig(D)"
names[names == "Evolutionary_distinctiveness_sum"] <- "EDsum"
names[names == "Pylo_diversity_is_sum_of_BL"] <- "PDsum"
names[names == "transition_rate_ratio_1to2_over_2to1"] <- "TR(ratio)"
names[names == "gamma"] <- "Gamma"
names[names == "mean_Phylogenetic_isolation"] <- "MPI"
names[names == "extrate"] <- "Ext(ratio)"
names[names == "average_phylogenetic_diversity_is_mean_of_BL"] <- "PDmean"
names[names == "extinction_per_speciation"] <- "DR"
names[names == "variance_Phylogenetic_isolation"] <- "VPI"
names[names == "F_quadratic_entropy_is_sum_of_PD"] <- "F"
names[names == "Mean_pairwise_distance"] <- "MPD"
names[names == "variance_Pylo_diversity_is_variance_of_BL"] <- "PDvar"
names[names == "variance_pairwise_distance"] <- "VPD"
png("var_import_all.png", width = 25, height = 25, unit="in", res=300)
par(mar = c(10, 18, 1, 1))
plot(x = rev(imp[, 5]), y = 1:nrow(imp), type = "l", yaxt = "n",
ylab = "", xlab = "Variable Importance",
xlim = c(0, 1), lwd = 2, cex.lab = 4)
for (i in 1:nrow(imp)) {
abline(h = i, lty = 3, col = "gray80")
}
abline(v = seq(0, 1, 1/19), lty = 3, col = "gray80")
lines(x = rev(imp[, 4]), y = 1:nrow(imp), col = "darkgreen", lwd = 2)
lines(x = rev(imp[, 3]), y = 1:nrow(imp), col = "red", lwd = 2)
lines(x = rev(imp[, 2]), y = 1:nrow(imp), col = "blue", lwd = 2)
lines(x = rev(imp[, 1]), y = 1:nrow(imp), col = "darkorange1", lwd = 2)
lines(x = rev(imp[, 5]), y = 1:nrow(imp), lwd = 3)
points(x = rev(imp[, 4]), y = 1:nrow(imp), col = "darkgreen", cex = 2)
points(x = rev(imp[, 3]), y = 1:nrow(imp), col = "red", cex = 2)
points(x = rev(imp[, 2]), y = 1:nrow(imp), col = "blue", cex = 2)
points(x = rev(imp[, 1]), y = 1:nrow(imp), col = "darkorange1", cex = 2)
points(x = rev(imp[, 5]), y = 1:nrow(imp), pch = 20, cex = 3)
text(y = 1:nrow(imp), x = par("usr")[1] - .17, labels = rev(names),
srt = 0, pos = 4, xpd = T, cex = 4)
dev.off()
null device
1
par(mfrow=c(2,3))
# Box plots
boxplot(spatial.tests.fora ~ Model, data = data.analysis.comp3)
abline(h = a$spatial.tests.fora, col = "red", lty = 2)
boxplot(spatial.tests.dom ~ Model, data = data.analysis.comp3)
abline(h = a$spatial.tests.fora, col = "red", lty = 2)
boxplot(log(sprate) ~ Model, data = data.analysis.comp3, ylim = c(-10, 10))
abline(h = log(a$sprate), col = "red", lty = 2)
boxplot(log(extrate) ~ Model, data = data.analysis.comp3, ylim = c(-10, 10))
abline(h = log(a$extrate), col = "red", lty = 2)
boxplot(log(transition_rate_ratio_1to2_over_2to1) ~ Model, data = data.analysis.comp3)
abline(h = log(a$sprate), col = "red", lty = 2)
boxplot(Phylogenetic_signal ~ Model, data = data.analysis.comp3, ylim = c(0, 1))
abline(h = a$Phylogenetic_signal, col = "red", lty = 2)

str(fit)
List of 19
$ call : language randomForest(formula = Model ~ ., data = train, xtest = test2, ytest = test1, importance = TRUE, ntree = 2400, keep.forest = TRUE)
$ type : chr "classification"
$ predicted : Factor w/ 4 levels "01","02","03",..: 1 3 1 1 3 3 3 1 3 1 ...
..- attr(*, "names")= chr [1:8885] "1" "2" "3" "4" ...
$ err.rate : num [1:2400, 1:5] 0.547 0.547 0.549 0.535 0.533 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr [1:5] "OOB" "01" "02" "03" ...
$ confusion : num [1:4, 1:5] 1392 298 434 90 230 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:4] "01" "02" "03" "04"
.. ..$ : chr [1:5] "01" "02" "03" "04" ...
$ votes : matrix [1:8885, 1:4] 0.549 0.346 0.906 0.902 0.22 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:8885] "1" "2" "3" "4" ...
.. ..$ : chr [1:4] "01" "02" "03" "04"
..- attr(*, "class")= chr [1:2] "matrix" "votes"
$ oob.times : num [1:8885] 907 876 855 911 850 863 879 836 883 902 ...
$ classes : chr [1:4] "01" "02" "03" "04"
$ importance : num [1:20, 1:6] 0.0248 0.0262 0.0149 0.012 0.0186 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:20] "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" "F_quadratic_entropy_is_sum_of_PD" ...
.. ..$ : chr [1:6] "01" "02" "03" "04" ...
$ importanceSD : num [1:20, 1:5] 0.000668 0.000584 0.00033 0.000355 0.000494 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:20] "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" "F_quadratic_entropy_is_sum_of_PD" ...
.. ..$ : chr [1:5] "01" "02" "03" "04" ...
$ localImportance: NULL
$ proximity : NULL
$ ntree : num 2400
$ mtry : num 4
$ forest :List of 14
..$ ndbigtree : int [1:2400] 3853 3761 3829 3805 3823 3977 3887 3917 3887 3907 ...
..$ nodestatus: int [1:4035, 1:2400] 1 1 1 1 1 1 1 1 1 1 ...
..$ bestvar : int [1:4035, 1:2400] 13 8 11 16 7 17 10 7 18 11 ...
..$ treemap : int [1:4035, 1:2, 1:2400] 2 4 6 8 10 12 14 16 18 20 ...
..$ nodepred : int [1:4035, 1:2400] 0 0 0 0 0 0 0 0 0 0 ...
..$ xbestsplit: num [1:4035, 1:2400] 193.4137 0.0287 0.9995 25.8679 33.4238 ...
..$ pid : num [1:4] 1 1 1 1
..$ cutoff : num [1:4] 0.25 0.25 0.25 0.25
..$ ncat : Named int [1:20] 1 1 1 1 1 1 1 1 1 1 ...
.. ..- attr(*, "names")= chr [1:20] "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" "F_quadratic_entropy_is_sum_of_PD" ...
..$ maxcat : int 1
..$ nrnodes : int 4035
..$ ntree : num 2400
..$ nclass : int 4
..$ xlevels :List of 20
.. ..$ Pylo_diversity_is_sum_of_BL : num 0
.. ..$ average_phylogenetic_diversity_is_mean_of_BL: num 0
.. ..$ variance_Pylo_diversity_is_variance_of_BL : num 0
.. ..$ F_quadratic_entropy_is_sum_of_PD : num 0
.. ..$ Mean_pairwise_distance : num 0
.. ..$ variance_pairwise_distance : num 0
.. ..$ Evolutionary_distinctiveness_sum : num 0
.. ..$ mean_Phylogenetic_isolation : num 0
.. ..$ variance_Phylogenetic_isolation : num 0
.. ..$ gamma : num 0
.. ..$ extinction_per_speciation : num 0
.. ..$ transition_from_trait_1_to_2 : num 0
.. ..$ transition_from_trait_2_to_1 : num 0
.. ..$ transition_rate_ratio_1to2_over_2to1 : num 0
.. ..$ Phylogenetic_signal : num 0
.. ..$ spatial.tests.fora : num 0
.. ..$ spatial.tests.dom : num 0
.. ..$ prevalence : num 0
.. ..$ sprate : num 0
.. ..$ extrate : num 0
$ y : Factor w/ 4 levels "01","02","03",..: 1 1 1 1 1 1 1 1 1 1 ...
..- attr(*, "names")= chr [1:8885] "1" "2" "3" "4" ...
$ test :List of 5
..$ predicted: Factor w/ 4 levels "01","02","03",..: 1 3 1 1 1 3 1 3 2 1 ...
.. ..- attr(*, "names")= chr [1:188] "1410" "86" "2307" "1834" ...
..$ err.rate : num [1:2400, 1:5] 0.559 0.537 0.473 0.479 0.473 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : NULL
.. .. ..$ : chr [1:5] "Test" "01" "02" "03" ...
..$ confusion: num [1:4, 1:5] 27 6 10 4 6 24 1 8 11 2 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:4] "01" "02" "03" "04"
.. .. ..$ : chr [1:5] "01" "02" "03" "04" ...
..$ votes : matrix [1:188, 1:4] 0.94 0.354 0.532 0.543 0.525 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:188] "1410" "86" "2307" "1834" ...
.. .. ..$ : chr [1:4] "01" "02" "03" "04"
.. ..- attr(*, "class")= chr [1:2] "matrix" "votes"
..$ proximity: NULL
$ inbag : NULL
$ terms :Classes 'terms', 'formula' language Model ~ Pylo_diversity_is_sum_of_BL + average_phylogenetic_diversity_is_mean_of_BL + variance_Pylo_diversity_is_variance_of_BL + F_quadratic_entropy_is_sum_of_PD + ...
.. ..- attr(*, "variables")= language list(Model, Pylo_diversity_is_sum_of_BL, average_phylogenetic_diversity_is_mean_of_BL, variance_Pylo_diversity_is_variance_of_BL, F_quadratic_entropy_is_sum_of_PD, ...
.. ..- attr(*, "factors")= int [1:21, 1:20] 0 1 0 0 0 0 0 0 0 0 ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : chr [1:21] "Model" "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" ...
.. .. .. ..$ : chr [1:20] "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" "F_quadratic_entropy_is_sum_of_PD" ...
.. ..- attr(*, "term.labels")= chr [1:20] "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" "F_quadratic_entropy_is_sum_of_PD" ...
.. ..- attr(*, "order")= int [1:20] 1 1 1 1 1 1 1 1 1 1 ...
.. ..- attr(*, "intercept")= num 0
.. ..- attr(*, "response")= int 1
.. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
.. ..- attr(*, "predvars")= language list(Model, Pylo_diversity_is_sum_of_BL, average_phylogenetic_diversity_is_mean_of_BL, variance_Pylo_diversity_is_variance_of_BL, F_quadratic_entropy_is_sum_of_PD, ...
.. ..- attr(*, "dataClasses")= Named chr [1:21] "factor" "numeric" "numeric" "numeric" ...
.. .. ..- attr(*, "names")= chr [1:21] "Model" "Pylo_diversity_is_sum_of_BL" "average_phylogenetic_diversity_is_mean_of_BL" "variance_Pylo_diversity_is_variance_of_BL" ...
- attr(*, "class")= chr [1:2] "randomForest.formula" "randomForest"
LS0tCnRpdGxlOiAiRC1wbGFjZSBGQVJNIGRvY3VtZW50YXRpb246IE1vZHVsZSAzIgphdXRob3I6ICJUeSBUdWZmLCBCcnVubyBWaWxlbGEsIGFuZCBDYXJsb3MgQm90ZXJvIgpkYXRlOiAncHJvamVjdCBiZWdhbjogMTUgTWF5IDIwMTYsIGRvY3VtZW50IHVwZGF0ZWQ6IGByIHN0cmZ0aW1lKFN5cy50aW1lKCksIGZvcm1hdAogID0gIiVkICVCICVZIilgJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0CmJpYmxpb2dyYXBoeTogRkFSTSBwYWNrYWdlLmJpYgotLS0KYGBge3J9CmxpYnJhcnkocG5nKQpgYGAKCgoKYGBge3J9CiMjIEZpcnN0IGNvbnNvbGlkYXRlIHRoZSBhdmFpbGFibGUgZmlsZXMgaW50byBhIHNpbmdsZSB0YWJsZQogICAgCiAgICAgIHBhdGggPC0gIn4vQm94IFN5bmMvRm91ciBtb2RlbCBjb21wYXJlL01vZHVsZSAyIgogICAgICAgICAgIAogICAgIAogICAgICAgICAgIHNldHdkKHBhdGgpCiAgICBteWZpbGVzX2Z1bGwgPC0gbGlzdC5kaXJzKCkKICAgIGFuYWx5emVfdGhpc19tYW55IDwtIGxlbmd0aChteWZpbGVzX2Z1bGwpCiAgICAKICAgIGF2YWlsYWJsZV9maWxlcyA8LSBtYXRyaXgoTkEsIDEsIDEpCiAgICAKICAgICAgICAKICAgIGZvcihpIGluIDE6IGFuYWx5emVfdGhpc19tYW55KXsKICAgIGF2YWlsYWJsZV9maWxlcyA8LSByYmluZChhdmFpbGFibGVfZmlsZXMgLCBhcy5tYXRyaXgobGlzdC5maWxlcyhteWZpbGVzX2Z1bGxbaV0sIGZ1bGwubmFtZXMgPSBUUlVFKSkpCiAgICB9CiAgICBkaW0oYXZhaWxhYmxlX2ZpbGVzKQogICAgCiAgICBzcGxpdC5maWxlLm5hbWUgPC0gc3Ryc3BsaXQoYXZhaWxhYmxlX2ZpbGVzWzEwXSwgc3BsaXQgPSAiXyIpIAogICAgCiAgICAKICAgIAogCmF2YWlsYWJsZSA8LSBsaXN0LmZpbGVzKCkKZmlsZXMgPC0gbWF0cml4KHJlcChOQSwgNjIpLCBsZW5ndGgoYXZhaWxhYmxlKSwgNjIpCmRpbShmaWxlcykKaSA8LSAxMAoKCmZvcihpIGluIDE6bGVuZ3RoKGF2YWlsYWJsZSkpewpsb2FkKGF2YWlsYWJsZVtpXSkKbmFtZSA8LSB1bmxpc3Qoc3Ryc3BsaXQoYXZhaWxhYmxlW2ldLCBzcGxpdD0iXyIpKQpmaWxlc1tpLF0gPC0gYyhhcy52ZWN0b3IobWF0cml4KG5hbWUsIDEsMzUpKSxtYXRyaXgoU2ltX3N0YXRpc3RpY3NbWzFdXSwgMSwgMjcpKQoKfQoKCmNvbG5hbWVzKGZpbGVzKSA8LSAgYygKCglOQSwKCSJiYWNrZ3JvdW5kX3Rha2VvdmVyX3R5cGUiICwKCU5BLAoJInJlcGxpY2F0ZSIsCglOQSwKCSJNb2RlbF90eXBlIiwKCXJlcChOQSwyKSwKCSJzcGVjaWF0aW9uX29mX0Vudl9Ob25EIiwKCSJzcGVjaWF0aW9uX29mX0Vudl9EIiwKCSJzcGVjaWF0aW9uX29mX0ZvciIsCgkic3BlY2lhdGlvbl9vZl9Eb20iLAoJTkEsCgkiZXh0aW5jdGlvbl9vZl9FbnZfTm9uRCIsCgkiZXh0aW5jdGlvbl9vZl9FbnZfRCIsCgkiZXh0aW5jdGlvbl9vZl9Gb3IiLAoJImV4dGluY3Rpb25fb2ZfRG9tIiwKCU5BLAoJIlAuZGlmZnVzaW9uX1RhcmdldF9mb3JhZ2VyIiwKCSJQLmRpZmZ1c2lvbl9UYXJnZXRfZG9tZXN0aWNhdG9yIiwKCSJQLmRpZmZ1c2lvbl9Tb3VyY2VfZm9yYWdlciIsCgkiUC5kaWZmdXNpb25fU291cmNlX2RvbWVzdGljYXRvciIsCglOQSwKCSJQLnRha2VvdmVyX1RhcmdldF9mb3JhZ2VyIiwKCSJQLnRha2VvdmVyX1RhcmdldF9kb21lc3RpY2F0b3IiLAoJIlAudGFrZW92ZXJfU291cmNlX2ZvcmFnZXIiLAoJIlAudGFrZW92ZXJfU291cmNlX2RvbWVzdGljYXRvciIsCglOQSwKCSJhcmlzYWxfb2ZfRW52X05vbkQiLAoJImFyaXNhbF9vZl9FbnZfRCIsCgkiYXJpc2FsX29mX0ZvciIsCgkiYXJpc2FsX29mX0RvbSIsCgkKCU5BLCAKCSJ0aW1lc3RlcHMiLCAKCU5BLAogICAgICAgIAogICAgIm51bWJlcl9vZl9icmFuY2hlcyIsCgkiUHlsb19kaXZlcnNpdHlfaXNfc3VtX29mX0JMIiwKCSJhdmVyYWdlX3BoeWxvZ2VuZXRpY19kaXZlcnNpdHlfaXNfbWVhbl9vZl9CTCIsCgkidmFyaWFuY2VfUHlsb19kaXZlcnNpdHlfaXNfdmFyaWFuY2Vfb2ZfQkwiLAoKCSJGX3F1YWRyYXRpY19lbnRyb3B5X2lzX3N1bV9vZl9QRCIsCgkiTWVhbl9wYWlyd2lzZV9kaXN0YW5jZSIsCgkidmFyaWFuY2VfcGFpcndpc2VfZGlzdGFuY2UiLAoKCSJFdm9sdXRpb25hcnlfZGlzdGluY3RpdmVuZXNzX3N1bSIsCgkibWVhbl9QaHlsb2dlbmV0aWNfaXNvbGF0aW9uIiwKCSJ2YXJpYW5jZV9QaHlsb2dlbmV0aWNfaXNvbGF0aW9uIiwKCgkiZ2FtbWEiLAoJImdhbW1hX3BfdmFsdWUiLAoJInNwZWNpYXRpb25fcmF0ZSIsCgkiZXh0aW5jdGlvbl9yYXRlIiwKCSJleHRpbmN0aW9uX3Blcl9zcGVjaWF0aW9uIiwKCSJzcGVjaWF0aW9uX21pbnVzX2V4dGluY3Rpb24iLAoJInRyYWl0XzFfc3BlY2lhdGlvbiIsCiAgCSJ0cmFpdF8yX3NwZWNpYXRpb24iICwKICAJInRyYWl0XzFfZXh0aW5jdGlvbiIgLAogIAkidHJhaXRfMl9leHRpbmN0aW9uIiAsCiAgCSJ0cmFuc2l0aW9uX2Zyb21fdHJhaXRfMV90b18yIiAsCiAgCSJ0cmFuc2l0aW9uX2Zyb21fdHJhaXRfMl90b18xIiAsCiAgCSJ0cmFuc2l0aW9uX3JhdGVfcmF0aW9fMXRvMl9vdmVyXzJ0bzEiICwKICAJIlBoeWxvZ2VuZXRpY19zaWduYWwiLAogIAkic3BhdGlhbC50ZXN0cy5mb3JhIiwKICAJInNwYXRpYWwudGVzdHMuZG9tIiwKICAJInByZXZhbGVuY2UiCiAgCQogICAgCiAgKQoKcmVzdWx0c190YWJsZSA8LSBhcy5kYXRhLmZyYW1lKGZpbGVzKQpoZWFkKHJlc3VsdHNfdGFibGUpCmRpbShyZXN1bHRzX3RhYmxlKQpDb25jYXRlbmF0ZWRfZGF0YSA8LSByZXN1bHRzX3RhYmxlCnNhdmUoQ29uY2F0ZW5hdGVkX2RhdGEsIGZpbGU9In4vRGVza3RvcC9Gb3VyX21vZGVsX2NvbXBhcmVfcmVzdWx0cy5SZGF0YSIpCgpvbmUgPC0gc3Vic2V0KHJlc3VsdHNfdGFibGUsIE1vZGVsX3R5cGU9PSIwMSIgKQp0d28gPC0gc3Vic2V0KHJlc3VsdHNfdGFibGUsIE1vZGVsX3R5cGU9PSIwMiIgKQp0aHJlZSA8LSBzdWJzZXQocmVzdWx0c190YWJsZSwgTW9kZWxfdHlwZT09IjAzIiApCmZvdXIgPC0gc3Vic2V0KHJlc3VsdHNfdGFibGUsIE1vZGVsX3R5cGU9PSIwNCIgKQpjcm9wIDwtIG1pbihsZW5ndGgob25lWywxXSksCmxlbmd0aCh0d29bLDFdKSwKbGVuZ3RoKHRocmVlWywxXSksCmxlbmd0aChmb3VyWywxXSkpCm9uZSA8LSBvbmVbMTpjcm9wLF0KdHdvIDwtIHR3b1sxOmNyb3AsXQp0aHJlZSA8LSB0aHJlZVsxOmNyb3AsXQpmb3VyIDwtIGZvdXJbMTpjcm9wLF0KCkNvbmNhdGVuYXRlZF9kYXRhIDwtIHJiaW5kKG9uZSwgdHdvLCB0aHJlZSwgZm91cikKZGltKENvbmNhdGVuYXRlZF9kYXRhKQoKCgoKCnNhdmUoQ29uY2F0ZW5hdGVkX2RhdGEsIGZpbGU9cGFzdGUwKCJ+L0JveCBTeW5jL2NvbGxpZGluZyByYW5nZXMvU2ltdWxhdGlvbnNfaHVtYW5zL1Jlc3VsdHMvYXZhaWxhYmxlIGRhaWx5IHN1bW1hcmllcy9Gb3VyX21vZGVsX2NvbXBhcmVfcmVzdWx0cyIsIGZvcm1hdChTeXMudGltZSgpLCBmb3JtYXQ9IiVkXyViXyVZIiksIl9jcm9wX3RvXyIsIGNyb3AsIi5SZGF0YSIpKQpjcm9wCgpgYGAKCgoKCmBgYHtyfQojIyBGaXJzdCBjb25zb2xpZGF0ZSB0aGUgYXZhaWxhYmxlIGZpbGVzIGludG8gYSBzaW5nbGUgdGFibGUKICAgIAogICAgICBwYXRoIDwtICJ+L0JveCBTeW5jL0ZvdXIgbW9kZWwgY29tcGFyZS9Nb2R1bGUgMiBleHRpbmN0IgogICAgICAgICAgIAogICAgIAogICAgICAgICAgIHNldHdkKHBhdGgpCiAgICBteWZpbGVzX2Z1bGwgPC0gbGlzdC5kaXJzKCkKICAgIGFuYWx5emVfdGhpc19tYW55IDwtIGxlbmd0aChteWZpbGVzX2Z1bGwpCiAgICAKICAgIGF2YWlsYWJsZV9maWxlcyA8LSBtYXRyaXgoTkEsIDEsIDEpCiAgICAKICAgICAgICAKICAgIGZvcihpIGluIDE6IGFuYWx5emVfdGhpc19tYW55KXsKICAgIGF2YWlsYWJsZV9maWxlcyA8LSByYmluZChhdmFpbGFibGVfZmlsZXMgLCBhcy5tYXRyaXgobGlzdC5maWxlcyhteWZpbGVzX2Z1bGxbaV0sIGZ1bGwubmFtZXMgPSBUUlVFKSkpCiAgICB9CiAgICBkaW0oYXZhaWxhYmxlX2ZpbGVzKQogICAgCiAgICBzcGxpdC5maWxlLm5hbWUgPC0gc3Ryc3BsaXQoYXZhaWxhYmxlX2ZpbGVzWzEwXSwgc3BsaXQgPSAiXyIpIAogICAgCiAgICAKICAgIAogCmF2YWlsYWJsZSA8LSBsaXN0LmZpbGVzKCkKZmlsZXMgPC0gbWF0cml4KHJlcChOQSwgNjIpLCBsZW5ndGgoYXZhaWxhYmxlKSwgNjIpCmRpbShmaWxlcykKaSA8LSAxMAoKCmZvcihpIGluIDE6bGVuZ3RoKGF2YWlsYWJsZSkpewpsb2FkKGF2YWlsYWJsZVtpXSkKbmFtZSA8LSB1bmxpc3Qoc3Ryc3BsaXQoYXZhaWxhYmxlW2ldLCBzcGxpdD0iXyIpKQpmaWxlc1tpLF0gPC0gYyhhcy52ZWN0b3IobWF0cml4KG5hbWUsIDEsMzUpKSxtYXRyaXgoU2ltX3N0YXRpc3RpY3NbWzFdXSwgMSwgMjcpKQoKfQoKCmNvbG5hbWVzKGZpbGVzKSA8LSAgYygKCglOQSwKCSJiYWNrZ3JvdW5kX3Rha2VvdmVyX3R5cGUiICwKCU5BLAoJInJlcGxpY2F0ZSIsCglOQSwKCSJNb2RlbF90eXBlIiwKCXJlcChOQSwyKSwKCSJzcGVjaWF0aW9uX29mX0Vudl9Ob25EIiwKCSJzcGVjaWF0aW9uX29mX0Vudl9EIiwKCSJzcGVjaWF0aW9uX29mX0ZvciIsCgkic3BlY2lhdGlvbl9vZl9Eb20iLAoJTkEsCgkiZXh0aW5jdGlvbl9vZl9FbnZfTm9uRCIsCgkiZXh0aW5jdGlvbl9vZl9FbnZfRCIsCgkiZXh0aW5jdGlvbl9vZl9Gb3IiLAoJImV4dGluY3Rpb25fb2ZfRG9tIiwKCU5BLAoJIlAuZGlmZnVzaW9uX1RhcmdldF9mb3JhZ2VyIiwKCSJQLmRpZmZ1c2lvbl9UYXJnZXRfZG9tZXN0aWNhdG9yIiwKCSJQLmRpZmZ1c2lvbl9Tb3VyY2VfZm9yYWdlciIsCgkiUC5kaWZmdXNpb25fU291cmNlX2RvbWVzdGljYXRvciIsCglOQSwKCSJQLnRha2VvdmVyX1RhcmdldF9mb3JhZ2VyIiwKCSJQLnRha2VvdmVyX1RhcmdldF9kb21lc3RpY2F0b3IiLAoJIlAudGFrZW92ZXJfU291cmNlX2ZvcmFnZXIiLAoJIlAudGFrZW92ZXJfU291cmNlX2RvbWVzdGljYXRvciIsCglOQSwKCSJhcmlzYWxfb2ZfRW52X05vbkQiLAoJImFyaXNhbF9vZl9FbnZfRCIsCgkiYXJpc2FsX29mX0ZvciIsCgkiYXJpc2FsX29mX0RvbSIsCgkKCU5BLCAKCSJ0aW1lc3RlcHMiLCAKCU5BLAogICAgICAgIAogICAgIm51bWJlcl9vZl9icmFuY2hlcyIsCgkiUHlsb19kaXZlcnNpdHlfaXNfc3VtX29mX0JMIiwKCSJhdmVyYWdlX3BoeWxvZ2VuZXRpY19kaXZlcnNpdHlfaXNfbWVhbl9vZl9CTCIsCgkidmFyaWFuY2VfUHlsb19kaXZlcnNpdHlfaXNfdmFyaWFuY2Vfb2ZfQkwiLAoKCSJGX3F1YWRyYXRpY19lbnRyb3B5X2lzX3N1bV9vZl9QRCIsCgkiTWVhbl9wYWlyd2lzZV9kaXN0YW5jZSIsCgkidmFyaWFuY2VfcGFpcndpc2VfZGlzdGFuY2UiLAoKCSJFdm9sdXRpb25hcnlfZGlzdGluY3RpdmVuZXNzX3N1bSIsCgkibWVhbl9QaHlsb2dlbmV0aWNfaXNvbGF0aW9uIiwKCSJ2YXJpYW5jZV9QaHlsb2dlbmV0aWNfaXNvbGF0aW9uIiwKCgkiZ2FtbWEiLAoJImdhbW1hX3BfdmFsdWUiLAoJInNwZWNpYXRpb25fcmF0ZSIsCgkiZXh0aW5jdGlvbl9yYXRlIiwKCSJleHRpbmN0aW9uX3Blcl9zcGVjaWF0aW9uIiwKCSJzcGVjaWF0aW9uX21pbnVzX2V4dGluY3Rpb24iLAoJInRyYWl0XzFfc3BlY2lhdGlvbiIsCiAgCSJ0cmFpdF8yX3NwZWNpYXRpb24iICwKICAJInRyYWl0XzFfZXh0aW5jdGlvbiIgLAogIAkidHJhaXRfMl9leHRpbmN0aW9uIiAsCiAgCSJ0cmFuc2l0aW9uX2Zyb21fdHJhaXRfMV90b18yIiAsCiAgCSJ0cmFuc2l0aW9uX2Zyb21fdHJhaXRfMl90b18xIiAsCiAgCSJ0cmFuc2l0aW9uX3JhdGVfcmF0aW9fMXRvMl9vdmVyXzJ0bzEiICwKICAJIlBoeWxvZ2VuZXRpY19zaWduYWwiLAogIAkic3BhdGlhbC50ZXN0cy5mb3JhIiwKICAJInNwYXRpYWwudGVzdHMuZG9tIiwKICAJInByZXZhbGVuY2UiCiAgCQogICAgCiAgKQoKQ29uY2F0ZW5hdGVkX2RhdGEgPC0gYXMuZGF0YS5mcmFtZShmaWxlcykKaGVhZChDb25jYXRlbmF0ZWRfZGF0YSkKZGltKENvbmNhdGVuYXRlZF9kYXRhKQoKc2F2ZShDb25jYXRlbmF0ZWRfZGF0YSwgZmlsZT1wYXN0ZTAoIn4vQm94IFN5bmMvY29sbGlkaW5nIHJhbmdlcy9TaW11bGF0aW9uc19odW1hbnMvUmVzdWx0cy9hdmFpbGFibGUgZGFpbHkgc3VtbWFyaWVzL0ZvdXJfbW9kZWxfY29tcGFyZV9yZXN1bHRzX2V4dGluY3RfIiwgZm9ybWF0KFN5cy50aW1lKCksIGZvcm1hdD0iJWRfJWJfJVkiKSwiX2Nyb3BfdG9fIiwgY3JvcCwiLlJkYXRhIikpCgpgYGAKCgpgYGB7cn0KbG9hZCgnfi9Cb3ggU3luYy9jb2xsaWRpbmcgcmFuZ2VzL1NpbXVsYXRpb25zX2h1bWFucy9SZXN1bHRzL2F2YWlsYWJsZSBkYWlseSBzdW1tYXJpZXMvRm91cl9tb2RlbF9jb21wYXJlX3Jlc3VsdHNfMDJfTWFyXzIwMTdfY3JvcF90b18zNDgxLlJkYXRhJykKZXh0YW50IDwtIENvbmNhdGVuYXRlZF9kYXRhCmV4dGFudApgYGAKCgoKCmBgYHtyfQpzZXR3ZCgifi9Cb3ggU3luYy9jb2xsaWRpbmcgcmFuZ2VzL1NpbXVsYXRpb25zX2h1bWFucy9SZXN1bHRzL2F2YWlsYWJsZSBkYWlseSBzdW1tYXJpZXMiKQpkZXRhaWxzIDwtIGZpbGUuaW5mbyhsaXN0LmZpbGVzKCkpCgp0cmltbWVkX2RldGFpbHMgPC0gZGV0YWlsc1t3aGljaChsaXN0LmZpbGVzKCkgPT0gbGlzdC5maWxlcyhwYXR0ZXJuID0gIkZvdXJfbW9kZWxfY29tcGFyZV9yZXN1bHRzX2V4dGluY3QqIikpLF0Kb3JkIDwtIG9yZGVyKHRyaW1tZWRfZGV0YWlscyRtdGltZSwgZGVjcmVhc2luZyA9IFRSVUUpCnJvd25hbWVzKHRyaW1tZWRfZGV0YWlsc1tvcmQsXSlbMV0KbG9hZChyb3duYW1lcyh0cmltbWVkX2RldGFpbHNbb3JkLF0pWzFdKQpleHRpbmN0IDwtIENvbmNhdGVuYXRlZF9kYXRhCgp0cmltbWVkX2RldGFpbHMgPC0gZGV0YWlsc1t3aGljaChsaXN0LmZpbGVzKCkgIT0gbGlzdC5maWxlcyhwYXR0ZXJuID0gIkZvdXJfbW9kZWxfY29tcGFyZV9yZXN1bHRzX2V4dGluY3QqIikpLF0Kb3JkIDwtIG9yZGVyKHRyaW1tZWRfZGV0YWlscyRtdGltZSwgZGVjcmVhc2luZyA9IFRSVUUpCnJvd25hbWVzKHRyaW1tZWRfZGV0YWlsc1tvcmQsXSlbMV0KbG9hZChyb3duYW1lcyh0cmltbWVkX2RldGFpbHNbb3JkLF0pWzFdKQpleHRhbnQgPC0gQ29uY2F0ZW5hdGVkX2RhdGEKCgoKCgpgYGAKCmBgYHtyfQpkaW0oZXh0aW5jdCkKZGltKGV4dGFudCkKYGBgCgoKCgpgYGB7cn0KCmZvcihpIGluIGMoOSwxMCwxMSwxMiwxNCwxNSwxNiwxNywxOSwyMCwyMSwyMiwyNCwyNSwyNiwyNywyOSwzMCwzMSwzMikpewoJZXh0aW5jdFt3aGljaChpcy5uYW4oYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssIGldKSkpID09IFRSVUUpLCBpXSA8LSBOQQp9Cgpmb3IoaSBpbiBjKDksMTAsMTEsMTIsMTQsMTUsMTYsMTcsMTksMjAsMjEsMjIsMjQsMjUsMjYsMjcsMjksMzAsMzEsMzIpKXsKCWV4dGFudFt3aGljaChpcy5uYW4oYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgaV0pKSkgPT0gVFJVRSksIGldIDwtIE5BCn0KCmkgPC0gMTkKZm9yKGkgaW4gYygyMCwyMSwyNCwyNSwyNiwyNykpewoJZXh0aW5jdFt3aGljaChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgaV0pKSA9PSAwKSwgaV0gPC0gTkEKfQoKZm9yKGkgaW4gYygyMCwyMSwyNCwyNSwyNiwyNykpewoJZXh0YW50W3doaWNoKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGFudFssIGldKSkgPT0gMCksIGldIDwtIE5BCn0KCgp4bGltaXQgPC0gYygwLDEpCnlsaW1pdCA8LSBjKDAsNjAwKQptYWluY2V4IDwtIDAuOQoKcG5nKGZpbGU9Ikdsb2JhbF9zdWNjZXNzX3JhdGVfcGVyX3BhcmFtZXRlci5wbmciLCB3aWR0aD04LjUsIGhlaWdodD0xMSwgdW5pdHM9ImluIiwgcmVzPTMwMCkKCnBhcihtZnJvdz1jKDUsNCksIG1hcj1jKDMsMywzLDApKQoKCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssOV0pKSwgbWFpbj0ic3BlY2lhdGlvbiBvZiBGIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0wLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLDldKSksIG1haW49InNwZWNpYXRpb24gb2YgRiBpbiBGIGVudiIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywxMF0pKSwgbWFpbj0ic3BlY2lhdGlvbiBvZiBEIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywxMF0pKSwgbWFpbj0ic3BlY2lhdGlvbiBvZiBEIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywxMV0pKSwgbWFpbj0ic3BlY2lhdGlvbiBvZiBGIGluIEQgZW52IiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywxMV0pKSwgbWFpbj0ic3BlY2lhdGlvbiBvZiBGIGluIEQgZW52IiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGluY3RbLDEyXSkpLCBtYWluPSJzcGVjaWF0aW9uIG9mIEQgaW4gRCBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLDEyXSkpLCBtYWluPSJzcGVjaWF0aW9uIG9mIEQgaW4gRCBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4LCBhZGQ9VFJVRSkKCiMjIyMjIyMKCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssIDE0XSkpLCBtYWluPSJleHRpbmN0aW9uIG9mIEYgaW4gRiBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAxNF0pKSwgbWFpbj0iZXh0aW5jdGlvbiBvZiBGIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgoKCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssIDE1XSkpLCBtYWluPSJleHRpbmN0aW9uIG9mIEQgaW4gRiBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAxNV0pKSwgbWFpbj0iZXh0aW5jdGlvbiBvZiBEIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGluY3RbLCAxNl0pKSwgbWFpbj0iZXh0aW5jdGlvbiBvZiBGIGluIEQgZW52IiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgMTZdKSksIG1haW49ImV4dGluY3Rpb24gb2YgRiBpbiBEIGVudiIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgsIGFkZD1UUlVFKQoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMTddKSksIG1haW49ImV4dGluY3Rpb24gb2YgRCBpbiBEIGVudiIsIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4KQpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGFudFssIDE3XSkpLCBtYWluPSJleHRpbmN0aW9uIG9mIEQgaW4gRCBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4LCBhZGQ9VFJVRSkKCiMjIyMjIwoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMjldKSksIG1haW49ImFyaXNhbCBvZiBGIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgMjldKSksIG1haW49ImFyaXNhbCBvZiBGIGluIEYgZW52IiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgoKCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssIDMwXSkpLCBtYWluPSJhcmlzYWwgb2YgRCBpbiBGIGVudiIsIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4KQpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGFudFssIDMwXSkpLCBtYWluPSJhcmlzYWwgb2YgRCBpbiBGIGVudiIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgsIGFkZD1UUlVFKQoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMzFdKSksIG1haW49ImFyaXNhbCBvZiBGIGluIEQgZW52IiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgMzFdKSksIG1haW49ImFyaXNhbCBvZiBGIGluIEQgZW52IiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGluY3RbLCAzMl0pKSwgbWFpbj0iYXJpc2FsIG9mIEQgaW4gRCBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAzMl0pKSwgbWFpbj0iYXJpc2FsIG9mIEQgaW4gRCBlbnYiLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4LCBhZGQ9VFJVRSkKCiMjIyMjIwoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMTldKSksIG1haW49Ik5PUEUgLS0gRGlmZnVzaW9uOiBzb3VyY2UgRiwgdGFyZ2V0IEYiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0gYygwLDE4MDAwKSwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgMTldKSksIG1haW49Ik5PUEUgLS0gRGlmZnVzaW9uOiBzb3VyY2UgRiwgdGFyZ2V0IEYiLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSBjKDAsMTgwMDApLCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgoKCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssIDIwXSkpLCBtYWluPSJEaWZmdXNpb246IHNvdXJjZSBELCB0YXJnZXQgRiIsIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4KQpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGFudFssIDIwXSkpLCBtYWluPSJEaWZmdXNpb246IHNvdXJjZSBELCB0YXJnZXQgRiIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgsIGFkZD1UUlVFKQoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMjFdKSksIG1haW49IkRpZmZ1c2lvbjogc291cmNlIEYsIHRhcmdldCBEIiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgMjFdKSksIG1haW49IkRpZmZ1c2lvbjogc291cmNlIEYsIHRhcmdldCBEIiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCwgYWRkPVRSVUUpCgpoaXN0KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGluY3RbLCAyMl0pKSwgbWFpbj0iTk9QRSAtLSBEaWZmdXNpb246IHNvdXJjZSBELCB0YXJnZXQgRCIsIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSBjKDAsMTgwMDApLCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAyMl0pKSwgbWFpbj0iTk9QRSAtLSBEaWZmdXNpb246IHNvdXJjZSBELCB0YXJnZXQgRCIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IGMoMCwxODAwMCksIGNleC5tYWluPSBtYWluY2V4LCBhZGQ9VFJVRSkKCiMjIyMKCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssIDI0XSkpLCBtYWluPSJUYWtlb3Zlcjogc291cmNlIEYsIHRhcmdldCBGIiwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgpCmhpc3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywgMjRdKSksIG1haW49IlRha2VvdmVyOiBzb3VyY2UgRiwgdGFyZ2V0IEYiLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuNyksIGJyZWFrcz0xMDAsIGJvcmRlcj1OQSwgeGxpbT0geGxpbWl0LCB5bGltPSB5bGltaXQsIGNleC5tYWluPSBtYWluY2V4LCBhZGQ9VFJVRSkKCgoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMjVdKSksIG1haW49IlRha2VvdmVyOiBzb3VyY2UgRCwgdGFyZ2V0IEYiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAyNV0pKSwgbWFpbj0iVGFrZW92ZXI6IHNvdXJjZSBELCB0YXJnZXQgRiIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgsIGFkZD1UUlVFKQoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMjZdKSksIG1haW49IlRha2VvdmVyOiBzb3VyY2UgRiwgdGFyZ2V0IEQiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAyNl0pKSwgbWFpbj0iVGFrZW92ZXI6IHNvdXJjZSBGLCB0YXJnZXQgRCIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgsIGFkZD1UUlVFKQoKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRpbmN0WywgMjddKSksIG1haW49IlRha2VvdmVyOiBzb3VyY2UgRCwgdGFyZ2V0IEQiLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjcpLCBicmVha3M9MTAwLCBib3JkZXI9TkEsIHhsaW09IHhsaW1pdCwgeWxpbT0geWxpbWl0LCBjZXgubWFpbj0gbWFpbmNleCkKaGlzdChhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLCAyN10pKSwgbWFpbj0iVGFrZW92ZXI6IHNvdXJjZSBELCB0YXJnZXQgRCIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC43KSwgYnJlYWtzPTEwMCwgYm9yZGVyPU5BLCB4bGltPSB4bGltaXQsIHlsaW09IHlsaW1pdCwgY2V4Lm1haW49IG1haW5jZXgsIGFkZD1UUlVFKQoKCmRldi5vZmYoKQoKCgoKCgpgYGAKCgohW10oR2xvYmFsX3N1Y2Nlc3NfcmF0ZV9wZXJfcGFyYW1ldGVyLnBuZykKCgpgYGB7cn0KCgoKcG5nKGZpbGU9ImV4dGljdGlvbiBtaW51cyBleHRhbnQgcGVyIG91dGNvbWUucG5nIiwgd2lkdGg9OC41LCBoZWlnaHQ9MTEsIHVuaXRzPSJpbiIsIHJlcz0zMDApCnBhcihtZnJvdz1jKDMsMSkpCgpwbG90KGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGluY3RbLDldKSksIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGluY3RbLDE0XSkpLCB4bGFiPSJzcGVjaWF0aW9uIiwgeWxhYj0iZXh0aW5jdGlvbiIsIGNvbD0gYWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPTAuMiksIHBjaD0xOSwgY2V4PTAuNiwgeWxpbT1jKDAsMSkpCnBsb3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50Wyw5XSkpLCBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihleHRhbnRbLDE0XSkpLCB4bGFiPSJzcGVjaWF0aW9uIiwgeWxhYj0iZXh0aW5jdGlvbiIsIGNvbD0gYWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC4yKSwgcGNoPTE5LCBjZXg9MC42LCB5bGltPWMoMCwxKSkKCnBsb3QoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssOV0pKSwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0aW5jdFssMTRdKSksIHhsYWI9InNwZWNpYXRpb24iLCB5bGFiPSJleHRpbmN0aW9uIiwgY29sPSBhZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9MC4yKSwgcGNoPTE5LCBjZXg9MC42LCB5bGltPWMoMCwxKSkKcG9pbnRzKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGV4dGFudFssOV0pKSwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZXh0YW50WywxNF0pKSwgeGxhYj0ic3BlY2lhdGlvbiIsIHlsYWI9ImV4dGluY3Rpb24iLCBjb2w9IGFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuMiksIHBjaD0xOSwgY2V4PTAuNikKCgpkZXYub2ZmKCkKCgpgYGAKCiFbXShleHRpY3Rpb24gbWludXMgZXh0YW50IHBlciBvdXRjb21lLnBuZykKCgoKYGBge3J9CgpwYXJhbXMgPC0gZXh0YW50WywtMTotMzVdCm5hbWVzKHBhcmFtcykKYnJlYWtfbnVtYmVyIDwtIDEwCnhtaW4gPC0KeG1heCA8LSAKCngxIDwtIGFzLm51bWVyaWMocGFyYW1zWywxXSkKaDEgPC0gaGlzdCh4MSwgIHBsb3Q9RkFMU0UsIGJyZWFrcz0gYnJlYWtfbnVtYmVyKQp4Zml0MSA8LSBzZXEoeG1pbiwgeG1heCwgbGVuZ3RoPSAxMDApCnlmaXQxIDwtIGRub3JtKHhmaXQxLCBtZWFuPW1lYW4oeDEpLCBzZD1zZCh4MSkpCnlmaXQxIDwtIHlmaXQxKmRpZmYoaDEkbWlkc1sxOjJdKSpsZW5ndGgoeDEpKzEwMS41CnBvbHlnb24oeGZpdDEsIHlmaXQxLCBjb2w9YWRqdXN0Y29sb3IoImxpbWVncmVlbiIsIGFscGhhPTAuNSksIGx3ZD0yLCBib3JkZXI9YWRqdXN0Y29sb3IoImxpbWVncmVlbiIsIGFscGhhPTAuNikpCgpgYGAKCgoKCgpgYGB7cn0KCgpsb2FkKCd+L0JveCBTeW5jL2NvbGxpZGluZyByYW5nZXMvU2ltdWxhdGlvbnNfaHVtYW5zL0F2YWlsYWJsZSB0cmVlcy9yZWFsLmFuYWx5c2lzLlJEYXRhJykKCkNvbmNhdGVuYXRlZF9kYXRhIDwtIGV4dGFudAoKI0NvbmNhdGVuYXRlZF9kYXRhIDwtIENvbmNhdGVuYXRlZF9kYXRhW0NvbmNhdGVuYXRlZF9kYXRhWywgMl0gPT0gInN0YXRzLm5vLmJUTyIsIF0KI0NvbmNhdGVuYXRlZF9kYXRhIDwtIENvbmNhdGVuYXRlZF9kYXRhW0NvbmNhdGVuYXRlZF9kYXRhWywgNl0gIT0gIjA1IiwgXQojIENvbmNhdGVuYXRlZF9kYXRhWywgNl0gPC0gYXMubnVtZXJpYyhDb25jYXRlbmF0ZWRfZGF0YVssIDZdKQojICMgQ29uY2F0ZW5hdGVkX2RhdGFbb3JpZ2luYWxbLCAyXSA9PSAiYmFja2dyb3VuZF90YWtlb3ZlciIsIDZdIDwtICBDb25jYXRlbmF0ZWRfZGF0YVtvcmlnaW5hbFssIDJdID09ICJiYWNrZ3JvdW5kX3Rha2VvdmVyIiwgNl0gKyA0CkNvbmNhdGVuYXRlZF9kYXRhWywgNl0gPC0gZmFjdG9yKENvbmNhdGVuYXRlZF9kYXRhWywgNl0pCiNoZWFkKENvbmNhdGVuYXRlZF9kYXRhKQojbmFtZXMoQ29uY2F0ZW5hdGVkX2RhdGEpCgpQQ0FkYXRhIDwtIENvbmNhdGVuYXRlZF9kYXRhWywgLSgxOjM1KV0KUENBZGF0YSA8LSBQQ0FkYXRhWywgLTEyXQpQQ0FkYXRhIDwtIGFwcGx5KFBDQWRhdGEsIDIsIGFzLm51bWVyaWMpCnJlbW92ZSA8LSBhcHBseShpcy5uYShQQ0FkYXRhKSwgMSwgYW55KQpQQ0FkYXRhIDwtIFBDQWRhdGFbIXJlbW92ZSwgXQoKIyBQcmVkaWN0aW9ucwpsaWJyYXJ5KHJhbmRvbUZvcmVzdCkKCmRhdGEuYW5hbHlzaXMuY29tcDIgPC0gZGF0YS5mcmFtZSgiTW9kZWwiID0gYXMuZmFjdG9yKENvbmNhdGVuYXRlZF9kYXRhWyFyZW1vdmUsIDZdKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBDQWRhdGEpCmRhdGEuYW5hbHlzaXMuY29tcDIkc3ByYXRlIDwtIGRhdGEuYW5hbHlzaXMuY29tcDIkdHJhaXRfMV9zcGVjaWF0aW9uL2RhdGEuYW5hbHlzaXMuY29tcDIkdHJhaXRfMl9zcGVjaWF0aW9uCmRhdGEuYW5hbHlzaXMuY29tcDIkZXh0cmF0ZSA8LSBkYXRhLmFuYWx5c2lzLmNvbXAyJHRyYWl0XzFfZXh0aW5jdGlvbi9kYXRhLmFuYWx5c2lzLmNvbXAyJHRyYWl0XzJfZXh0aW5jdGlvbgoKCiNsb2FkKCJSZWFsX3BoeS9yZWFsLmFuYWx5c2lzLlJEYXRhIikKYSA8LSBhcy5kYXRhLmZyYW1lKHJlYWwuYW5hbHlzaXMkcmVzdWx0c19zdW1tYXJ5X29mX3NpbmdsZV92YWx1ZV9vdXRwdXRzKQphJHNwcmF0ZSA8LSBhJHRyYWl0XzFfc3BlY2lhdGlvbiAvIGEkdHJhaXRfMl9zcGVjaWF0aW9uCmEkZXh0cmF0ZSA8LSBhJHRyYWl0XzFfZXh0aW5jdGlvbiAvIGEkdHJhaXRfMl9leHRpbmN0aW9uCgpkYXRhLmFuYWx5c2lzLmNvbXAzIDwtIGRhdGEuYW5hbHlzaXMuY29tcDJbLCAtYygyLCAxMzoxNCwgMTY6MjApXQojZGF0YS5hbmFseXNpcy5jb21wMyA8LSBkYXRhLmFuYWx5c2lzLmNvbXAzW2RhdGEuYW5hbHlzaXMuY29tcDMkTW9kZWwgJWluJSAxOjQsIF0KI2RhdGEuYW5hbHlzaXMuY29tcDMkTW9kZWwgPC0gZmFjdG9yKGRhdGEuYW5hbHlzaXMuY29tcDMkTW9kZWwpCiNzdWIgPC0gdW5saXN0KGxhcHBseShhcy5saXN0KGMoMTo0KSksIGZ1bmN0aW9uKHgsIHkpIHsKIyAgc2FtcGxlKHdoaWNoKHkkTW9kZWwgPT0geCksIG1pbih0YWJsZShkYXRhLmFuYWx5c2lzLmNvbXAzJE1vZGVsKSkpfSwKIyAgeSA9IGRhdGEuYW5hbHlzaXMuY29tcDMpKQojIGRhdGEuYW5hbHlzaXMuY29tcDMgPC0gZGF0YS5hbmFseXNpcy5jb21wM1tzdWIsIF0KZnVuIDwtIGZ1bmN0aW9uKHgsIHksIHBlciA9IC4zMykge3NhbXBsZSh3aGljaCh5JE1vZGVsID09IHgpLCByb3VuZCh0YWJsZSh5JE1vZGVsKVsxXSpwZXIpKX0KCnN1Yi50ZXN0IDwtIHVubGlzdChsYXBwbHkoYXMubGlzdChwYXN0ZTAoMCwgYygxOjQpKSksIGZ1biwKICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZGF0YS5hbmFseXNpcy5jb21wMykpCnRlc3QyIDwtIGRhdGEuYW5hbHlzaXMuY29tcDNbc3ViLnRlc3QsIDI6bmNvbChkYXRhLmFuYWx5c2lzLmNvbXAzKV0KdGVzdDEgPC0gZGF0YS5hbmFseXNpcy5jb21wM1tzdWIudGVzdCwgMV0KdHJhaW4gPC0gZGF0YS5hbmFseXNpcy5jb21wM1stc3ViLnRlc3QsIF0KCmZvcihpIGluIDE6MTAwKXsKKGZpdCA8LSByYW5kb21Gb3Jlc3QoTW9kZWwgfiAuLCBkYXRhPXRyYWluLCB4dGVzdCA9IHRlc3QyLCB5dGVzdCA9IHRlc3QxLCAKICAgICAgICAgICAgICAgICAgICBpbXBvcnRhbmNlPVRSVUUsIG50cmVlPTEwMDAsIGtlZXAuZm9yZXN0ID0gRkFMU0UsIHJlcGxhY2U9RkFMU0UpKQoKcHJlZGljdGlvbnMgPC0gcHJlZGljdChmaXQsIAogICAgICAgICAgICAgICAgICAgICAgIGEsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZT0icHJvYiIpCnByZWRpY3Rpb25zCgpzYXZlKGZpdCwgZmlsZT1wYXN0ZTAoIn4vQm94IFN5bmMvY29sbGlkaW5nIHJhbmdlcy9TaW11bGF0aW9uc19odW1hbnMvUmVzdWx0cy9SRl9kYWlseV9vdXRwdXQvUkZfZGFpbHlfb3V0cHV0XyIsIGZvcm1hdChTeXMudGltZSgpLCBmb3JtYXQ9IiVkXyViXyVZIiksICJfIixpLCAiX05vUkVQTEFDRU1FTlRfLlJkYXRhIikpCn0KYGBgCgpgYGB7cn0KCgpzYXZlKGZpdCwgZmlsZT1wYXN0ZTAoIn4vQm94IFN5bmMvY29sbGlkaW5nIHJhbmdlcy9TaW11bGF0aW9uc19odW1hbnMvUmVzdWx0cy9SRl9kYWlseV9vdXRwdXQvUkZfZGFpbHlfb3V0cHV0XyIsIGZvcm1hdChTeXMudGltZSgpLCBmb3JtYXQ9IiVkXyViXyVZIiksIi5SZGF0YSIpKQpgYGAKCgoKCmBgYHtyfQoKcGxvdChmaXQsIHlsaW09YygwLDEpKQoKYGBgCgoKCgpgYGB7cn0KbGFicyA8LSBjKCJCYXNpYyIsICIrRGlmZnVzaW9uIiwgIitUYWtlb3ZlciIsICIrRGlmZnVzaW9uICtUYWtlb3ZlciIpCgpgYGAKCgpgYGB7cn0KIyBiYXIgcGxvdApwbmcoIlByb2JfYXVzLnBuZyIsIHdpZHRoID0gMjUsIGhlaWdodCA9IDI1LCByZXMgPSAzMDAsIHVuaXRzID0gImluIikKcGFyKG1hciA9IGMoOCwgOCwgMSwgMSkpCnByZWQgPC0gc2V0TmFtZXMoYXMubnVtZXJpYyhwcmVkaWN0aW9ucyksIGxhYnMpCmNvbHMgPC0gcmV2KGMoImRhcmtncmVlbiIsICJyZWQiLCAiYmx1ZSIsICJkYXJrb3JhbmdlMSIpKQpiYXJwbG90KHByZWQsIGNvbCA9IGNvbHMsIHlsYWIgPSAiUHJvYWJpbGl0eSIsIGNleC5sYWIgPSAzLCBjZXgubmFtZXMgPSAyKQpkZXYub2ZmKCkKYGBgCgohW10oUHJvYl9hdXMucG5nKQoKCmBgYHtyfQojIFBsb3QgY29uZnVzaW9uIG1hdHJpeApwbmcoIkNvbmZmdXNpb25fbWF0cml4X2FsbC5wbmciLCB3aWR0aCA9IDI1LCBoZWlnaHQgPSAyNSwgcmVzPTMwMCwgdW5pdHM9ImluIikKcGFyKG1hciA9IGMoMTAsIDExLCAxLCAxKSkKY29sb3JzMSA8LSBjb2xvclJhbXBQYWxldHRlKGNvbG9ycyA9IGMoIiNmMGYwZjAiLCAiI2JkYmRiZCIsIiM2MzYzNjMiKSkKcHJvcCA8LSBhcHBseShmaXQkY29uZnVzaW9uWywgLTVdLCAyLCBmdW5jdGlvbih4KXt4IC8gc3VtKHgpfSkgKiAxMDAKCmltYWdlKHByb3AsIGNvbCA9IGNvbG9yczEoMjApLCBheGVzPUZBTFNFKQpheGlzKDEsIGF0PWMoMCwgLjMzLCAuNjYsIDEpLCBsYWJlbHM9bGFicywgdGljayA9IEZBTFNFLCBsaW5lID0gRkFMU0UsIGNleC5heGlzID0gMy41LCBwb3MgPSAtLjE5KQpheGlzKDIsIGF0PWMoMCwgLjMzLCAuNjYsIDEpLCBsYWJlbHM9bGFicywgdGljayA9IEZBTFNFLCBsaW5lID0gRkFMU0UsIGNleC5heGlzID0gMy41KQptdGV4dCgiQUNUVUFMIiwgc2lkZSA9IDEsIHBhZGogPSAzLCBjZXggPSA0KQptdGV4dCgiUFJFRElDVEVEIiwgc2lkZSA9IDIsIHBhZGogPSAtMywgY2V4ID0gNCkKCmZvcihpIGluIDE6NCkgewogIGZvcihqIGluIDE6NCkgewogICAgdGV4dCh4ID0gYygwLCAuMzMsIC42NiwgMSlbaV0sIHkgPSBjKDAsIC4zMywgLjY2LCAxKVtqXSwgcGFzdGUwKHJvdW5kKHByb3BbaSwgal0sIDIpLCAiJSIpLAogICAgICAgICBjZXggPSA1KQogIH0KfQpkZXYub2ZmKCkKYGBgCgoKIVtdKENvbmZmdXNpb25fbWF0cml4X2FsbC5wbmcpCgoKYGBge3J9CmltcG9ydGFuY2UoZml0KQpgYGAKCgpgYGB7cn0KIyBWYXJpYWJsZXMgaW1wb3J0YW5jZQoKaW1wIDwtIGltcG9ydGFuY2UoZml0KQppbXAgPC0gYXBwbHkoaW1wLCAyLCBmdW5jdGlvbih4KSAoeCAtIG1pbih4KSkvKG1heCh4KSAtIG1pbih4KSkpCmltcCA8LSBpbXBbc29ydChpbXBbLCA1XSwgaW5kZXgucmV0dXJuID0gVFJVRSwgZGVjcmVhc2luZyA9IFRSVUUpJGl4LCBdCgoKbmFtZXMgPC0gcm93bmFtZXMoaW1wKQpuYW1lc1tuYW1lcyA9PSAic3BhdGlhbC50ZXN0cy5mb3JhIl0gPC0gIlNwYWNlIEYiCm5hbWVzW25hbWVzID09ICJzcGF0aWFsLnRlc3RzLmRvbSJdIDwtICJTcGFjZSBEIgpuYW1lc1tuYW1lcyA9PSAic3ByYXRlIl0gPC0gIlNwKHJhdGlvKSIKbmFtZXNbbmFtZXMgPT0gInRyYW5zaXRpb25fZnJvbV90cmFpdF8xX3RvXzIiXSA8LSAiVFIoMS0yKSIKbmFtZXNbbmFtZXMgPT0gInRyYW5zaXRpb25fZnJvbV90cmFpdF8yX3RvXzEiXSA8LSAiVFIoMi0xKSIKbmFtZXNbbmFtZXMgPT0gIlBoeWxvZ2VuZXRpY19zaWduYWwiXSA8LSAiUGh5U2lnKEQpIgpuYW1lc1tuYW1lcyA9PSAiRXZvbHV0aW9uYXJ5X2Rpc3RpbmN0aXZlbmVzc19zdW0iXSA8LSAiRURzdW0iCm5hbWVzW25hbWVzID09ICJQeWxvX2RpdmVyc2l0eV9pc19zdW1fb2ZfQkwiXSA8LSAiUERzdW0iCm5hbWVzW25hbWVzID09ICJ0cmFuc2l0aW9uX3JhdGVfcmF0aW9fMXRvMl9vdmVyXzJ0bzEiXSA8LSAiVFIocmF0aW8pIgpuYW1lc1tuYW1lcyA9PSAiZ2FtbWEiXSA8LSAiR2FtbWEiCm5hbWVzW25hbWVzID09ICJtZWFuX1BoeWxvZ2VuZXRpY19pc29sYXRpb24iXSA8LSAiTVBJIgpuYW1lc1tuYW1lcyA9PSAiZXh0cmF0ZSJdIDwtICJFeHQocmF0aW8pIgpuYW1lc1tuYW1lcyA9PSAiYXZlcmFnZV9waHlsb2dlbmV0aWNfZGl2ZXJzaXR5X2lzX21lYW5fb2ZfQkwiXSA8LSAiUERtZWFuIgpuYW1lc1tuYW1lcyA9PSAiZXh0aW5jdGlvbl9wZXJfc3BlY2lhdGlvbiJdIDwtICJEUiIKbmFtZXNbbmFtZXMgPT0gInZhcmlhbmNlX1BoeWxvZ2VuZXRpY19pc29sYXRpb24iXSA8LSAiVlBJIgpuYW1lc1tuYW1lcyA9PSAiRl9xdWFkcmF0aWNfZW50cm9weV9pc19zdW1fb2ZfUEQiXSA8LSAiRiIKbmFtZXNbbmFtZXMgPT0gIk1lYW5fcGFpcndpc2VfZGlzdGFuY2UiXSA8LSAiTVBEIgpuYW1lc1tuYW1lcyA9PSAidmFyaWFuY2VfUHlsb19kaXZlcnNpdHlfaXNfdmFyaWFuY2Vfb2ZfQkwiXSA8LSAiUER2YXIiCm5hbWVzW25hbWVzID09ICJ2YXJpYW5jZV9wYWlyd2lzZV9kaXN0YW5jZSJdIDwtICJWUEQiCgoKcG5nKCJ2YXJfaW1wb3J0X2FsbC5wbmciLCB3aWR0aCA9IDI1LCBoZWlnaHQgPSAyNSwgdW5pdD0iaW4iLCByZXM9MzAwKQpwYXIobWFyID0gYygxMCwgMTgsIDEsIDEpKQpwbG90KHggPSByZXYoaW1wWywgNV0pLCB5ID0gMTpucm93KGltcCksIHR5cGUgPSAibCIsIHlheHQgPSAibiIsIAogICAgIHlsYWIgPSAiIiwgeGxhYiA9ICJWYXJpYWJsZSBJbXBvcnRhbmNlIiwKICAgICB4bGltID0gYygwLCAxKSwgbHdkID0gMiwgY2V4LmxhYiA9IDQpCmZvciAoaSBpbiAxOm5yb3coaW1wKSkgewogIGFibGluZShoID0gaSwgbHR5ID0gMywgY29sID0gImdyYXk4MCIpCn0KYWJsaW5lKHYgPSBzZXEoMCwgMSwgMS8xOSksIGx0eSA9IDMsIGNvbCA9ICJncmF5ODAiKQoKbGluZXMoeCA9IHJldihpbXBbLCA0XSksIHkgPSAxOm5yb3coaW1wKSwgY29sID0gImRhcmtncmVlbiIsIGx3ZCA9IDIpCmxpbmVzKHggPSByZXYoaW1wWywgM10pLCB5ID0gMTpucm93KGltcCksIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQpsaW5lcyh4ID0gcmV2KGltcFssIDJdKSwgeSA9IDE6bnJvdyhpbXApLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIpCmxpbmVzKHggPSByZXYoaW1wWywgMV0pLCB5ID0gMTpucm93KGltcCksIGNvbCA9ICJkYXJrb3JhbmdlMSIsIGx3ZCA9IDIpCmxpbmVzKHggPSByZXYoaW1wWywgNV0pLCB5ID0gMTpucm93KGltcCksIGx3ZCA9IDMpCgpwb2ludHMoeCA9IHJldihpbXBbLCA0XSksIHkgPSAxOm5yb3coaW1wKSwgY29sID0gImRhcmtncmVlbiIsIGNleCA9IDIpCnBvaW50cyh4ID0gcmV2KGltcFssIDNdKSwgeSA9IDE6bnJvdyhpbXApLCBjb2wgPSAicmVkIiwgY2V4ID0gMikKcG9pbnRzKHggPSByZXYoaW1wWywgMl0pLCB5ID0gMTpucm93KGltcCksIGNvbCA9ICJibHVlIiwgY2V4ID0gMikKcG9pbnRzKHggPSByZXYoaW1wWywgMV0pLCB5ID0gMTpucm93KGltcCksIGNvbCA9ICJkYXJrb3JhbmdlMSIsIGNleCA9IDIpCnBvaW50cyh4ID0gcmV2KGltcFssIDVdKSwgeSA9IDE6bnJvdyhpbXApLCBwY2ggPSAyMCwgY2V4ID0gMykKCgp0ZXh0KHkgPSAxOm5yb3coaW1wKSwgeCA9IHBhcigidXNyIilbMV0gLSAuMTcsIGxhYmVscyA9IHJldihuYW1lcyksCiAgICAgc3J0ID0gMCwgcG9zID0gNCwgeHBkID0gVCwgY2V4ID0gNCkKZGV2Lm9mZigpCmBgYAoKIVtdKHZhcl9pbXBvcnRfYWxsLnBuZykKCgoKCmBgYHtyfQpwYXIobWZyb3c9YygyLDMpKQoKIyBCb3ggcGxvdHMKYm94cGxvdChzcGF0aWFsLnRlc3RzLmZvcmEgfiBNb2RlbCwgZGF0YSA9IGRhdGEuYW5hbHlzaXMuY29tcDMpCmFibGluZShoID0gYSRzcGF0aWFsLnRlc3RzLmZvcmEsIGNvbCA9ICJyZWQiLCBsdHkgPSAyKQoKYm94cGxvdChzcGF0aWFsLnRlc3RzLmRvbSB+IE1vZGVsLCBkYXRhID0gZGF0YS5hbmFseXNpcy5jb21wMykKYWJsaW5lKGggPSBhJHNwYXRpYWwudGVzdHMuZm9yYSwgY29sID0gInJlZCIsIGx0eSA9IDIpCgpib3hwbG90KGxvZyhzcHJhdGUpIH4gTW9kZWwsIGRhdGEgPSBkYXRhLmFuYWx5c2lzLmNvbXAzLCB5bGltID0gYygtMTAsIDEwKSkKYWJsaW5lKGggPSBsb2coYSRzcHJhdGUpLCBjb2wgPSAicmVkIiwgbHR5ID0gMikKCmJveHBsb3QobG9nKGV4dHJhdGUpIH4gTW9kZWwsIGRhdGEgPSBkYXRhLmFuYWx5c2lzLmNvbXAzLCB5bGltID0gYygtMTAsIDEwKSkKYWJsaW5lKGggPSBsb2coYSRleHRyYXRlKSwgY29sID0gInJlZCIsIGx0eSA9IDIpCgpib3hwbG90KGxvZyh0cmFuc2l0aW9uX3JhdGVfcmF0aW9fMXRvMl9vdmVyXzJ0bzEpIH4gTW9kZWwsIGRhdGEgPSBkYXRhLmFuYWx5c2lzLmNvbXAzKQphYmxpbmUoaCA9IGxvZyhhJHNwcmF0ZSksIGNvbCA9ICJyZWQiLCBsdHkgPSAyKQoKYm94cGxvdChQaHlsb2dlbmV0aWNfc2lnbmFsIH4gTW9kZWwsIGRhdGEgPSBkYXRhLmFuYWx5c2lzLmNvbXAzLCB5bGltID0gYygwLCAxKSkKYWJsaW5lKGggPSBhJFBoeWxvZ2VuZXRpY19zaWduYWwsIGNvbCA9ICJyZWQiLCBsdHkgPSAyKQoKCmBgYAoKCgpgYGB7cn0KI2J1aWxkIGEgZGF0YSB0cmFja2luZyB0YWJsZSB0byB0cmFjayBwYXJhbWV0ZXIgY2hhbmdlcyB0aHJvdWdoIHRpbWUKCnN0cihmaXQpCgp5CgpgYGAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==